package com.lagou.rpc.consumer.proxy;

import com.alibaba.fastjson.JSON;
import com.lagou.rpc.common.RpcRequest;
import com.lagou.rpc.common.RpcResponse;
import com.lagou.rpc.consumer.Server;
import com.lagou.rpc.consumer.Servers;
import com.lagou.rpc.consumer.client.RpcClient;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;

/**
 * 客户端代理类-创建代理对象
 * 1.封装request请求对象
 * 2.创建RpcClient对象
 * 3.发送消息
 * 4.返回结果
 *
 * @author user
 */
@Servers(
        value = {
                @Server(ip = "127.0.0.1", port = 8899),
                @Server(ip = "127.0.0.1", port = 8889),
        }
)
public class RpcClientProxy {


    private static RpcClient createRpcClient() throws Exception {
        Servers servers = RpcClientProxy.class.getAnnotation(Servers.class);
        Server[] value = servers.value();
        int index = (int) (Math.random() * value.length);
        Server server = value[index];
        return new RpcClient(server.ip(), server.port());
    }

    public static Object createProxy(Class serviceClass) {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{serviceClass}, (proxy, method, args) -> {
            //1.封装request请求对象
            RpcRequest rpcRequest = new RpcRequest();
            rpcRequest.setRequestId(UUID.randomUUID().toString());
            rpcRequest.setClassName(method.getDeclaringClass().getName());
            rpcRequest.setMethodName(method.getName());
            rpcRequest.setParameterTypes(method.getParameterTypes());
            rpcRequest.setParameters(args);
            RpcClient rpcClient = null;
            try {
                //2.创建RpcClient对象
                rpcClient = createRpcClient();
                //3.发送消息
                Object responseMsg = rpcClient.send(JSON.toJSONString(rpcRequest));
                RpcResponse rpcResponse = JSON.parseObject(responseMsg.toString(), RpcResponse.class);
                if (rpcResponse.getError() != null) {
                    throw new RuntimeException(rpcResponse.getError());
                }
                //4.返回结果
                Object result = rpcResponse.getResult();
                return JSON.parseObject(result.toString(), method.getReturnType());
            } catch (Exception e) {
                throw e;
            } finally {
                if (rpcClient != null) {
                    rpcClient.close();
                }
            }

        });
    }
}
